package com.springcloud.tools.conf;

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.google.common.collect.Lists;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.List;

/**
 * @author fuc
 * @create 2020-06-09
 */
@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
@ConditionalOnProperty(name = "swagger.enabled", havingValue = "true")
public class SwaggerConfiguration {

  @Bean(value = "defaultApi2")
  public Docket defaultApi2() {
    ParameterBuilder parameterBuilder = new ParameterBuilder();
    List<Parameter> parameters = Lists.newArrayList();
    parameterBuilder
        .name("token")
        .description("token令牌")
        .modelRef(new ModelRef("String"))
        .parameterType("header")
        .required(true)
        .build();
    parameters.add(parameterBuilder.build());

    Docket docket =
        new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            .groupName("默认接口-swaggermodels")
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.springcloud.tools"))
            // .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
            .paths(PathSelectors.any())
            .build()
            .globalOperationParameters(parameters)
            .securityContexts(Lists.newArrayList(securityContext()))
            .securitySchemes(Lists.<SecurityScheme>newArrayList(apiKey()));
    return docket;
  }

  private ApiInfo apiInfo() {
    return new ApiInfoBuilder()
        .title("swagger-bootstrap-ui RESTful APIs")
        .description("# swagger-bootstrap-ui RESTful APIs")
        .termsOfServiceUrl("http://www.xx.com/")
        .contact("xx@qq.com")
        .version("1.0")
        .build();
  }

  private SecurityContext securityContext() {
    return SecurityContext.builder()
        .securityReferences(defaultAuth())
        .forPaths(PathSelectors.regex("/.*"))
        .build();
  }

  List<SecurityReference> defaultAuth() {
    AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
    AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
    authorizationScopes[0] = authorizationScope;
    return Lists.newArrayList(new SecurityReference("BearerToken", authorizationScopes));
  }

  private ApiKey apiKey() {
    // HttpHeaders.AUTHORIZATION
    return new ApiKey("BearerToken", "Authorization", "header");
  }
}
